import numpy as np
import pandas as pd

from sklearn.model_selection import train_test_split
import torch
import torch.nn as nn
import torch.optim as optim
import optuna
# 假设我们有一个数据集 data.csv，包含 x1, x2, x3 和 yi 列
data = pd.read_csv('data7.csv',encoding='gbk')

# 提取特征和目标变量
X = data[['x1', 'x2', 'x3']]
y1 = data['y']
y2=y1[1:1+48]
y = np.arange(16)
y = pd.Series(y)
for i in range(16):
    y[i]=(y2[i*3+1]+y2[i*3+2]+y2[i*3+3])/3
#y = y[]
#创建多项式特征
# X['x1_x2'] = X['x1'] * X['x2']
# X['x1_x3'] = X['x1'] * X['x3']
# X['x2_x3'] = X['x2'] * X['x3']
# X['x1_squared'] = X['x1'] ** 2
# X['x2_squared'] = X['x2'] ** 2
# X['x3_squared'] = X['x3'] ** 2
# X['x3_cube'] = X['x3'] ** 3
X=X[0:16]
# 标准化特征数据
# scaler = StandardScaler()
# X = scaler.fit_transform(X)=
X=X.values
# 转换为 DataFrame
#X = pd.DataFrame(X, columns=X.columns)
#划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)


# 转换为 PyTorch 张量
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)
y_test = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1)

# 定义神经网络模型
class NeuralNetwork(nn.Module):
    def __init__(self, input_dim):
        super(NeuralNetwork, self).__init__()
        self.fc1 = nn.Linear(input_dim, 64)
        self.fc2 = nn.Linear(64, 16)
        self.fc3 = nn.Linear(16, 1)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))

        x = self.fc3(x)
        return x

# 初始化模型、损失函数和优化器
model = NeuralNetwork(X_train.shape[1])
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 20000
for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()
    outputs = model(X_train)
    loss = criterion(outputs, y_train)
    loss.backward()
    optimizer.step()

    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
    if loss.item()<0.001:
        break;

# 评估模型
model.eval()
with torch.no_grad():
    predictions = model(X_test)
    mse = criterion(predictions, y_test)
    print(f"Mean Squared Error on test set: {mse.item():.4f}")

# 打印预测结果
for i in range(3):
    print(f"Actual: {y_test[i].item()}, Predicted: {predictions[i].item()}")
def objective(trial):
    # 2. 使用trial对象建议超参数取值
    x1 = trial.suggest_categorical('x1', [15, 20, 25, 30])
    x2 = trial.suggest_categorical('x2', [100, 110, 120, 130])
    x3 = trial.suggest_categorical('x3', [0, 10, 20, 30])
    #data = loadData('mackey_glass_t17.npy')
    x_x = torch.tensor([x1,x2,x3,x3*x3,x3*x3*x3], dtype=torch.float32)
    max = model(x_x);

    return max
# 创建Optuna study
study = optuna.create_study(direction='maximize')

 # 运行Optuna搜索
study.optimize(objective, n_trials=100)

# 打印最佳超参数和得分
print('Best hyperparameters: ', study.best_params)

print('Best score: ', study.best_value)
